//
// Created by ole on 24-8-21.
//

#ifndef PLUGINMANAGER_H
#define PLUGINMANAGER_H
#include <memory>
#include <unordered_map>
#include "BasePlugin.h"
#include "PluginWrapper.h"

class PluginManager {
public:
    std::string TAG = "PluginManager";

    static PluginManager &instance();

    PluginManager(const PluginManager &) = delete;

    PluginManager &operator=(const PluginManager &) = delete;

    void initialize();

    void dispose();

    void loopForever();

    std::shared_ptr<BasePlugin> getPlugin(const std::string &name);

    IPCManager &getIpcManager();

private:
    typedef std::unordered_map<std::string, std::shared_ptr<PluginWrapper> >::iterator PluginIterator;

    PluginManager() = default;

    void loadDynamicPlugins();

    void loadPlugins();

    void unloadPlugins();

    void loadCorePlugins();

    void registerPlugin(const std::shared_ptr<PluginWrapper> &plugin);

    template<typename T>
    std::shared_ptr<T> getShared(T &instance);

    PluginIterator unregisterPlugin(PluginIterator it);

    std::unordered_map<std::string, std::shared_ptr<PluginWrapper> > plugins;

    bool hasStarted = false;

    IPCManager ipcManager;
    std::mutex pluginsMutex;
};


#endif //PLUGINMANAGER_H
